package com.easylinkin.linkappapi.location.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.easylinkin.linkappapi.annotation.CommonOperateLogAnnotate;
import com.easylinkin.linkappapi.common.exceptions.BusinessException;
import com.easylinkin.linkappapi.common.model.RequestModel;
import com.easylinkin.linkappapi.common.utils.StringUtil;
import com.easylinkin.linkappapi.common.utils.async.AsyncUtil;
import com.easylinkin.linkappapi.lobar.dto.excel.ExcelResultDTO;
import com.easylinkin.linkappapi.location.entity.LinkappLocationDevice;
import com.easylinkin.linkappapi.location.entity.dto.DeviceQueryDto;
import com.easylinkin.linkappapi.location.entity.dto.IndoorLocationDto;
import com.easylinkin.linkappapi.location.entity.dto.PeopleQueryDto;
import com.easylinkin.linkappapi.location.service.ILinkappLocationDeviceService;
import com.easylinkin.linkappapi.operatelog.LogHelper;
import com.easylinkin.linkappapi.operatelog.constant.LogConstant.LogModule;
import com.easylinkin.linkappapi.operatelog.constant.LogConstant.LogOperateType;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import site.morn.rest.RestBuilders;
import site.morn.rest.RestMessage;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 定位设备
 *
 * @author JG
 * @since 2023-09-20
 */
@Api(tags = "定位设备管理")
@RestController
@RequestMapping("/location/linkappLocationDevice")
public class LinkappLocationDeviceController {
    @Autowired
    private ILinkappLocationDeviceService linkappLocationDeviceService;

    @Autowired
    private LinkappUserContextProducer linkappUserContextProducer;

    @Autowired
    private ResourceLoader resourceLoader;

    /**
     * 分页列表查询
     *
     * @param requestModel
     * @return
     */
//    @ApiOperation(value="分页列表查询", notes="分页列表查询")
//    @PostMapping(value = "/listPage")
//    public RestMessage queryPageList(@RequestBody RequestModel<LinkappLocationDevice> requestModel) {
//        // Assert.notNull(requestModel,"参数不能为空");
//        // Assert.notNull(requestModel.getCustomQueryParams(), "customQueryParams 不能为空");
//        Assert.notNull(requestModel.getPage(), "page 不能为空");
//        if(CollUtil.isNotEmpty(requestModel.getSorts())){
//            requestModel.getSorts().forEach(s -> {
//                requestModel.getPage().getOrders().add(new OrderItem().setColumn(StrUtil.toUnderlineCase(s.getField())).setAsc("ASC".equalsIgnoreCase(s.getSortRule())));
//            });
//        }else{
//            requestModel.getPage().getOrders().add(new OrderItem().setColumn("id").setAsc(false));
//        }
//        IPage<LinkappLocationDevice> pageList = linkappLocationDeviceService.page(requestModel.getPage(), Wrappers.lambdaQuery(requestModel.getCustomQueryParams()));
//        return RestBuilders.successBuilder().data(pageList).build();
//    }

    @ApiOperation("安全帽分页列表查询")
    @PostMapping("/queryList")
    public RestMessage queryList(@RequestBody RequestModel<DeviceQueryDto> requestModel) {
        return linkappLocationDeviceService.queryList(requestModel);
    }

    /**
    * @Description: 批量绑定
    * @Param: [file]
    * @return: site.morn.rest.RestMessage
    * @Author: 胡明威
    * @Date: 2023/9/21
    */
    @ApiOperation("批量绑定")
    @PostMapping("/import")
    @CommonOperateLogAnnotate(module = LogModule.PEOPLE_LOCATION, desc = "")
    public RestMessage importExcel(@NotNull @RequestPart("file") MultipartFile file) throws Exception {
        //记录日志
        if(file != null){
            String fileName = file.getOriginalFilename();
            LogHelper.setContent(LogOperateType.LOCATION_DEVICE_BATCH_IMPORT, fileName);
        }
        //获取当前时间的时间
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String key = "locationDevice:" + formatter.format(calendar.getTime());
        LinkappUser currentUserInfo = linkappUserContextProducer.getNotNullCurrent();
        AsyncUtil.submitTask(key, () ->{
            ExcelResultDTO resultDTO = null;
            try {
                resultDTO = linkappLocationDeviceService.importExcel(file, currentUserInfo);
            } catch (Exception e) {
                throw new BusinessException(e.getMessage());
            }
            return resultDTO;
        });
        return RestBuilders.successBuilder().data(key).build();
    }

    @ApiOperation("批量解绑")
    @PostMapping("/untie")
    @CommonOperateLogAnnotate(module = LogModule.PEOPLE_LOCATION, desc = "")
    public RestMessage untieBatch(@RequestBody LinkappLocationDevice linkappLocationDevice) {
        Assert.notNull(linkappLocationDevice.getIds(), "设备id不能为空");
        // 记录日志详情
        if (CollectionUtil.isNotEmpty(linkappLocationDevice.getIds())) {
            LogHelper.setContent(LogOperateType.LOCATION_DEVICE_UNTIE, linkappLocationDevice.getIds());
        }
        return linkappLocationDeviceService.untie(linkappLocationDevice.getIds());
    }

    /**
     * 保存
     *
     * @param linkappLocationDevice
     * @return
     */
//    @ApiOperation(value="保存", notes="保存")
//    @PostMapping(value = "/save")
//    public RestMessage save(@RequestBody LinkappLocationDevice linkappLocationDevice) {
//        if(linkappLocationDevice.getId() != null){
//            linkappLocationDeviceService.updateById(linkappLocationDevice);
//        } else{
//            linkappLocationDeviceService.save(linkappLocationDevice);
//        }
//        return RestBuilders.successBuilder().message("保存成功" ).build();
//    }

    /**
     * 安全帽人员绑定
     *
     * @param linkappLocationDevice
     * @return
     */
    @ApiOperation("安全帽人员绑定/解绑")
    @PostMapping(value = "/bindDevice")
    public RestMessage bindDevice(@RequestBody LinkappLocationDevice linkappLocationDevice) {
        Assert.notNull(linkappLocationDevice.getId(), "安全帽设备id不能为空");
        Assert.notNull(linkappLocationDevice.getBindControl(), "绑定/解绑控制参数不能为空");
        LinkappUser curUserInfo = linkappUserContextProducer.getNotNullCurrent();
        LambdaUpdateWrapper<LinkappLocationDevice> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(LinkappLocationDevice::getModifyId, curUserInfo.getId());
        wrapper.set(LinkappLocationDevice::getModifyTime, new Date());
        // 解绑
        if (linkappLocationDevice.getBindControl() == 0) {
            wrapper.set(LinkappLocationDevice::getBindState, 0);
            wrapper.set(LinkappLocationDevice::getBindTime, null);
            wrapper.set(LinkappLocationDevice::getUserId, null);
        } else if (linkappLocationDevice.getBindControl() == 1) {
            // 若不传userId，则判定为 未生效
            if (StringUtils.isBlank(linkappLocationDevice.getUserId())) {
                if (StringUtils.isBlank(linkappLocationDevice.getCardNo())) {
                    throw new BusinessException("身份证号不能为空");
                }
                wrapper.set(LinkappLocationDevice::getBindState, 2);
            } else {
                wrapper.set(LinkappLocationDevice::getBindState, 1);
            }
            wrapper.set(LinkappLocationDevice::getUserId, StringUtils.isBlank(linkappLocationDevice.getUserId()) ? linkappLocationDevice.getCardNo() : linkappLocationDevice.getUserId());
            wrapper.set(LinkappLocationDevice::getBindTime, new Date());
        } else {
            throw new BusinessException("绑定/解绑控制参数错误");
        }
        wrapper.eq(LinkappLocationDevice::getId, linkappLocationDevice.getId());
        linkappLocationDeviceService.update(wrapper);
        return RestBuilders.successBuilder().message("操作成功" ).build();
    }

    @ApiOperation("安全帽数据同步")
    @PostMapping("/synchronizeLocationDevice")
    @CommonOperateLogAnnotate(module = LogModule.PEOPLE_LOCATION, desc = "")
    public RestMessage synchronizeLocationDevice() {
        //获取当前时间的时间
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        String logName = "synchronizeLocationDevice:" + formatter.format(calendar.getTime());
        LogHelper.setContent(LogOperateType.LOCATION_DEVICE_SYNC, logName);
        return linkappLocationDeviceService.synchronizeLocationDevice();
    }

    @ApiOperation("人员信息查询")
    @PostMapping("/queryPeopleInfo")
    public RestMessage queryPeopleInfo(@RequestBody PeopleQueryDto dto) {
        Assert.notNull(dto.getUserId(), "用户id不能为空");
        return linkappLocationDeviceService.queryPeopleInfo(dto);
    }

    @ApiOperation("大屏-人员定位-获取打点数据")
    @PostMapping("/getLocationPoints")
    public RestMessage getLocationPoints() {
        return linkappLocationDeviceService.getLocationPoints();
    }

    @ApiOperation("大屏-人员室内定位")
    @PostMapping("/getIndoorLocationInfo")
    public RestMessage getIndoorLocationInfo(@RequestBody IndoorLocationDto dto) {
        return linkappLocationDeviceService.getIndoorLocationInfo(dto);
    }

    @ApiOperation("大屏-获取人数统计信息")
    @GetMapping("/getScreenCount")
    public RestMessage getScreenCount() {
        return linkappLocationDeviceService.countNumberOfDevicePeople();
    }

    /**
     * 下载模板
     * @param response
     * @throws IOException
     */
    @GetMapping("exportRealTemplate")
    @ApiOperation("下载模板")
    public void exportRealTemplate(HttpServletResponse response) throws IOException {
        try {
            Resource resource = resourceLoader.getResource("classpath:templates/safeHat.xlsx");
            InputStream inputStream = resource.getInputStream();
            byte[] fileSource = IOUtils.toByteArray(inputStream);
            //防止对原数据进行操作
            byte[] fileBytes = Arrays.copyOf(fileSource, fileSource.length);
            String name = "安全帽批量绑定模板";
            //下载模板
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(name,"UTF-8") + ".xlsx");
            response.setHeader("Content-Type", "application/vnd.ms-excel");
            response.setCharacterEncoding("UTF-8");
            response.getOutputStream().write(fileBytes);
            response.setContentLength(fileBytes.length);
        } finally {
            if (response.getOutputStream() != null) {
                response.getOutputStream().flush();
            }
        }
    }



    /**
     *   通过id删除
     *
     * @param id
     * @return
     */
//    @ApiOperation(value="通过id删除", notes="通过id删除")
//    @DeleteMapping(value = "/delete")
//    public RestMessage delete(@RequestParam("id") Integer id) {
//        linkappLocationDeviceService.removeById(id);
//        return RestBuilders.successBuilder().message("删除成功").build();
//    }

    /**
     *  批量删除
     *
     * @param ids
     * @return
     */
//    @ApiOperation(value="批量删除", notes="批量删除")
//    @DeleteMapping(value = "/deleteBatch")
//    public RestMessage deleteBatch(@RequestParam("ids") String ids) {
//        this.linkappLocationDeviceService.removeByIds(Arrays.asList(ids.split(",")));
//        return RestBuilders.successBuilder().message("批量删除成功").build();
//    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
//    @ApiOperation(value="通过id查询", notes="通过id查询")
//    @GetMapping(value = "/queryById")
//    public RestMessage queryById(@RequestParam("id") Integer id) {
//        LinkappLocationDevice linkappLocationDevice = linkappLocationDeviceService.getById(id);
//        if(linkappLocationDevice == null) {
//            return RestBuilders.errorBuilder().message("未找到对应数据").build();
//        }
//        return RestBuilders.successBuilder().data(linkappLocationDevice).build();
//    }
}
